﻿using System;
using System.Collections.Generic;
using System.Threading;

namespace PascalTriangle
{
    public class Solver
    {
        private TriangleContainer container;
        private Semaphore globalSemaphore;
        private bool allSolved;

        private int id;
        public int ID
        {
            get { return id; }
            set { id = value; }
        }

        private int points;
        public int Points
        {
            get { return points; }
            set { points = value; }
        }


        public Solver(TriangleContainer container, int ID, Semaphore sem)
        {
            this.container = container;
            this.allSolved = false;
            this.id = ID;
            this.points = 0;
            this.globalSemaphore = sem;
        }

        public void Run()
        {
            globalSemaphore.WaitOne();

            for (int i = 0; i < container.Level; i++)
            {
                for (int j = 0; j < container.Level; j++)
                {
                    long val = container.table[i,j].Val;

                    if (val != 0) 
                    {
                        container.table[i,j].ReleaseSemaphore();
                        continue;
                    }

                    if (i == 0 || j == 0 || j == container.Level - 1) 
                    {
                        val = 1;
                    }
                    else 
                    {
                        long first = 0;
                        long second = 0;

                        while(first == 0 || second == 0) 
                        {
                            first = container.table[i-1,j-1].Val;
                            container.table[i-1,j-1].ReleaseSemaphore();

                            second = container.table[i-1,j].Val;
                            container.table[i-1,j].ReleaseSemaphore();
                        }

                        val = first + second;
                    }

                    container.table[i,j].Val = val;
                    container.table[i,j].ReleaseSemaphore();

                    container.table[i, j].ThreadID = id;
                    points++;
                    Thread.Sleep(2);
                }
            }

            globalSemaphore.Release();
        }
    }
}
